package com.ssy.lingxi.settle.accounts.utils;

import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.List;

/**
 * 数值类型工具类
 * @author 万宁
 * @version 2.0.0
 * @date 2021-04-06
 */
public class NumberUtil {

    /**
     * 判断字符串是否为一个Long类型
     * @param value 字符串
     * @return true - 不是， false - 是
     */
    public static boolean notLongOrNegative(String value) {
        try {
            long v = Long.parseLong(value);
            return v < 0;
        } catch (Exception e) {
            return true;
        }
    }

    /**
     * 判断字符串是否为一个Long类型
     * @param value 字符串
     * @return true - 不是， false - 是
     */
    public static boolean notDoubleOrNegative(String value) {
        try {
            Double.parseDouble(value);
            return false;
        } catch (Exception e) {
            return true;
        }
    }

    /**
     * 判断Integer是否不为Null且不等于0
     * @param i Integer参数
     * @return 是-true，否-false
     */
    public static boolean notNullOrZero(Integer i) {
        return i != null && !i.equals(0);
    }

    /**
     * 判断Long是否不为Null且不等于0
     * @param l Long参数
     * @return 是-true，否-false
     */
    public static boolean notNullOrZero(Long l) {
        return l != null && !l.equals(0L);
    }

    /**
     * 判断BigDecimal是否不为Null且大于0
     * @param b BigDecimal参数
     * @return 是-true，否-false
     */
    public static boolean notNullAndPositive(BigDecimal b) {
        return b != null && b.compareTo(BigDecimal.ZERO) > 0;
    }

    /**
     * 判断BigDecimal是否不为Null且大于0
     * @param b BigDecimal参数
     * @return 是-true，否-false
     */
    public static boolean notNullAndPositiveZero(BigDecimal b) {
        return b != null && b.compareTo(BigDecimal.ZERO) >= 0;
    }

    /**
     * 判断Long是否不为Null且大于0
     * @param l Long参数
     * @return 是-true，否-false
     */
    public static boolean notNullAndPositive(Long l) {
        return l != null && l.compareTo(0L) > 0;
    }

    /**
     * 判断Integer是否不为Null且大于0
     * @param i Integer参数
     * @return 是-true，否-false
     */
    public static boolean notNullAndPositive(Integer i) {
        return i != null && i.compareTo(0) > 0;
    }

    /**
     * 判断Integer是否为Null或等于0
     * @param i Integer参数
     * @return 是-true，否-false
     */
    public static boolean isNullOrZero(Integer i) {
        return i == null || i.equals(0);
    }

    /**
     * 判断BigDecimal是否为Null或小于等于0
     * @param b BigDecimal参数
     * @return 是-true，否-false
     */
    public static boolean isNullOrZero(BigDecimal b) {
        return b == null || b.compareTo(BigDecimal.ZERO) <= 0;
    }

    /**
     * 判断Double是否为Null或小于等于0
     * @param d Double参数
     * @return 是-true，否-false
     */
    public static boolean isNullOrZero(Double d) {
        return d == null || d.compareTo(0D) <= 0;
    }

    /**
     * 判断Long是否为Null或负数
     * @param l Long参数
     * @return 是-true，否-false
     */
    public static boolean isNullOrNegative(Long l) {
        return l == null || l.compareTo(0L) < 0;
    }

    /**
     * 判断Double是否为Null或负数
     * @param d Double参数
     * @return 是-true，否-false
     */
    public static boolean isNullOrNegative(Double d) {
        return d == null || d.compareTo(0D) < 0;
    }

    /**
     * 判断Long是否为Null或非正数
     * @param l Long参数
     * @return 是-true，否-false
     */
    public static boolean isNullOrNegativeZero(Long l) {
        return l == null || l.compareTo(0L) <= 0;
    }

    /**
     * 判断Double是否为Null或非正数
     * @param d Double参数
     * @return 是-true，否-false
     */
    public static boolean isNullOrNegativeZero(Double d) {
        return d == null || d.compareTo(0D) <= 0;
    }

    /**
     * 判断Integer是否为Null或非正数
     * @param i Integer参数
     * @return 是-true，否-false
     */
    public static boolean isNullOrNegativeZero(Integer i) {
        return i == null || i.compareTo(0) <= 0;
    }

    /**
     * 判断Long是否为Null或非正数
     * @param b Long参数
     * @return 是-true，否-false
     */
    public static boolean isNullOrNegativeZero(BigDecimal b) {
        return b == null || b.compareTo(BigDecimal.ZERO) <= 0;
    }

    /**
     * 判断BigDecimal是否为Null或负数
     * @param b BigDecimal参数
     * @return 是-true，否-false
     */
    public static boolean isNullOrNegative(BigDecimal b) {
        return b == null || b.compareTo(BigDecimal.ZERO) < 0;
    }

    /**
     * 判断Integer是否为Null或负数
     * @param i Integer参数
     * @return 是-true，否-false
     */
    public static boolean isNullOrNegative(Integer i) {
        return i == null || i.compareTo(0) < 0;
    }

    /**
     * 判断Long是否为Null或等于0
     * @param l Long参数
     * @return 是-true，否-false
     */
    public static boolean isNullOrZero(Long l) {
        return l == null || l.equals(0L);
    }

    /**
     * 格式化BigDecimal金额，保留两位小数
     * @param bigDecimal 金额
     * @return 金额字符串
     */
    public static String formatAmount(BigDecimal bigDecimal) {
        if(bigDecimal == null) {
            return "0.00";
        }

        DecimalFormat df = new DecimalFormat("#0.00");
        return df.format(bigDecimal);
    }

    public static BigDecimal max(BigDecimal a, BigDecimal b) {
        return a.compareTo(b) >= 0 ? a : b;
    }

    /**
     * 格式化BigDecimal百分比小数，乘以100后转换为分子部分的字符串
     * @param bigDecimal 百分比小数
     * @return 百分比分子部分的整数字符串
     */
    public static String formatRoundHalfUp(BigDecimal bigDecimal) {
        if(bigDecimal == null) {
            return "0";
        }

        return bigDecimal.multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
    }

    /**
     * 格式化支付比例小数，保留2位小数，如果无小数，返回整数
     * @param bigDecimal 百分比小数
     * @return 百分比分子部分的整数字符串
     */
    public static String formatPayRate(BigDecimal bigDecimal) {
        if(bigDecimal == null) {
            return "0";
        }

        DecimalFormat df = new DecimalFormat("#.##");
        return df.format(bigDecimal.multiply(BigDecimal.valueOf(100)).setScale(0, RoundingMode.HALF_UP));
    }

    /**
     * 如果有小数，保留3位小数，如果无小数，返回整数
     * @param bigDecimal 数字
     * @return 字符串
     */
    public static String formatToInteger(BigDecimal bigDecimal) {
        if(bigDecimal == null) {
            return "0";
        }

        DecimalFormat df = new DecimalFormat("#.###");
        return df.format(bigDecimal);
    }

    /**
     * 如果有小数，保留一位小数，如果无小数，返回整数
     * @param bigDecimal 数字
     * @return 字符串
     */
    public static String formatHours(BigDecimal bigDecimal) {
        DecimalFormat df = new DecimalFormat("#.#");
        return df.format(bigDecimal);
    }

    /**
     * 判断两个List<Long>是否相同
     * @param first 第一个List
     * @param second 第二个List
     * @return 是-true，否-false
     */
    public static boolean longListEquals(List<Long> first , List<Long> second) {
        if(CollectionUtils.isEmpty(first) && CollectionUtils.isEmpty(second)) {
            return true;
        }

        if(CollectionUtils.isEmpty(first) && !CollectionUtils.isEmpty(second)) {
            return false;
        }

        if(!CollectionUtils.isEmpty(first) && CollectionUtils.isEmpty(second)) {
            return false;
        }

        if(first.size() != second.size()) {
            return false;
        }

        if(!first.stream().allMatch(f -> second.stream().anyMatch(s -> s.equals(f)))) {
            return false;
        }

        return second.stream().allMatch(s -> first.stream().anyMatch(f ->f.equals(s)));
    }

    /**
     * 判断两个List<Integer>是否相同
     * @param first 第一个List
     * @param second 第二个List
     * @return 是-true，否-false
     */
    public static boolean integerListEquals(List<Integer> first , List<Integer> second) {
        if(CollectionUtils.isEmpty(first) && CollectionUtils.isEmpty(second)) {
            return true;
        }

        if(CollectionUtils.isEmpty(first) && !CollectionUtils.isEmpty(second)) {
            return false;
        }

        if(!CollectionUtils.isEmpty(first) && CollectionUtils.isEmpty(second)) {
            return false;
        }

        if(first.size() != second.size()) {
            return false;
        }

        if(!first.stream().allMatch(f -> second.stream().anyMatch(s -> s.equals(f)))) {
            return false;
        }

        return second.stream().allMatch(s -> first.stream().anyMatch(f ->f.equals(s)));
    }
}
